*! NJC 1.2.0 11 January 2000
* NJC 1.1.0 7 January 2000
* John Moran suggested -frac( )- 
program define _grndsub 
	version 6        
        gettoken type 0 : 0
        gettoken g 0 : 0
        gettoken eqs 0 : 0
        gettoken lparen 0 : 0, parse("(")
        gettoken rparen 0 : 0, parse(")")
        syntax [if] [in] [, by(varlist) NGroup(int 2) Frac(str) Percent(str)]

	if "`frac'" != "" | "`percent'" != "" { 
		if "`frac'" != "" & "`percent'" != "" { 
			di in r "may not combine frac( ) and percent( )" 
			exit 198 
		}	
		else { 
			local opt = cond("`frac'" != "", "frac", "percent")  
			if `ngroup' != 2 { 
				di in r "`opt'( ) allowed only with ngroup(2)" 
				exit 198 
			}
		}	
		
		if "`percent'" != "" { 
			confirm number `percent' 
			capture assert `percent' > 0 & `percent' < 100 
			if _rc { 
				di in r "percent( ) should be between 0 and 100"
				exit 198 
			}
			local frac = 100 / `percent' 
		} 
		else { 
			confirm number `frac' 
			capture assert `frac' > 0 
			if _rc { 
				di in r "frac( ) should be > 0" 
				exit 198 
			}	
		} 	
	} 	
	
	tempvar touse random  
	quietly {
		mark `touse' `if' `in'
		gen `random' = uniform( ) 		
		sort `touse' `by' `random' 
		if "`frac'" != "" { 
			by `touse' `by' : gen `type' `g' = /* 
			*/ 1 + (_n  > (_N / `frac')) if `touse' 
		} 	
		else { 
			by `touse' `by': gen `type' `g' = /*
			*/ group(`ngroup') if `touse' 
		} 	
	}
end
